package aes.client;

import javax.swing.*;

import ocsf.client.ObservableClient;

import common.*;

import java.awt.event.*;
import java.util.*;

public class ClientUI extends JFrame implements Observer{
	
	public static final int LOGIN_SCREEN = 1;
	public static final int SETTINGS_SCREEN = 2;
	public static final int CREATE_USER = 3;
	public static final int MAIN_SCREEN = 4;
	public static final int QUESTIONS_MANAGER_SCREEN = 5;
	public static final int EXAMS_MANAGER_SCREEN = 6;
	public static final int CONNECTOR_SCREEN = 7;
	public static final int QUESTION_EDITOR_SCREEN = 8;
	public static final int EXAMS_EDITOR_SCREEN = 9;
	public static final int ADD_QUESTION_TO_EXAM_SCREEN = 10;
	public static final int TEACHER_EXAM_EXECUTION_SCREEN = 11;
	public static final int TEACHER_EXAM_COMPUTERIZED_EXECUTION_SCREEN = 12;
	public static final int TEACHER_EXAM_MANUAL_EXECUTION_SCREEN = 13;
	public static final int STUDENT_EXAM_EXECUTION_SCREEN = 14;
	public static final int PRINCIPAL_EXAM_EXECUTION_SCREEN = 15;
	public static final int EXAM_EXECUTION_FORM_SCREEN = 16;
	public static final int EXAM_EXECUTION_MANAGER_SCREEN = 17;
	public static final int STUDENT_REPORT_SCREEN = 18;
	public static final int EXAM_EXECUTION_MANUAL_FORM_SCREEN = 19;
	public static final int TEACHER_REPORT_SCREEN = 20;
	public static final int TEACHER_REPORT_EXAM_INFO_SCREEN = 21;
	public static final int GRADE_APPROVAL_SCREEN = 22;
	public static final int MANUAL_EXAM_GRADE_APPROVAL_SCREEN = 23;
	public static final int PRINCIPAL_REPORTS_SCREEN = 24;
	public static final int PRINCIPAL_STUDENT_REPORT_SCREEN = 25;
	public static final int PRINCIPAL_TEACHER_REPORT_SCREEN = 26;
	public static final int PRINCIPAL_COURSE_REPORT_SCREEN = 27;

	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int currentScreen = 0;
	private Client client = null;
	private User u = null;
	private int lastScreen = 0;

	/**
	 * Constructor
	 */
	public ClientUI(Client c) {
		client = c;
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("AES Client");
		
		JMenuBar menuBar = new JMenuBar();
		JMenu fileMenu = new JMenu("File");
		menuBar.add(fileMenu);
		JMenuItem exitMenu = new JMenuItem("Exit");
		exitMenu.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
		
		JMenuItem mntmCreateUser = new JMenuItem("Create User");
		fileMenu.add(mntmCreateUser);
		fileMenu.add(exitMenu);
		mntmCreateUser.addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent arg0) {
																	SetContent(CREATE_USER);
																}
															});
		
		JMenu optionsMenu = new JMenu("Options");
		menuBar.add(optionsMenu);
		
		JMenuItem settingsMenu = new JMenuItem("Settings");
		settingsMenu.addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent arg0) {
																	SetContent(SETTINGS_SCREEN);
																}
															});
		optionsMenu.add(settingsMenu);
		
		setJMenuBar(menuBar);
		
		pack();
		setSize(640,480);
	}
	
	/**
	 * Handle massage from Observable class in our case Client
	 */
	@Override
	public void update(Observable arg0, Object arg1) {
		String msg = "";
		if (arg1 instanceof TextMessage)
			msg = ((TextMessage)arg1).ToDebugMessage();
		else if (arg1 instanceof CommandMessage) {
			CommandMessage ms=(CommandMessage)arg1;
			if(ms.getCommand().equals(CommandMessage.ACKNOWLEDGE_MESSAGE)){
				String cmd=(String)(ms.getParams()[0]);
				if(cmd.equals(CommandMessage.LOGIN_MESSAGE))
				{
					if(ms.getParams()[1]==null)
						ShowMessageBox("Error ", "Wrong credentials" ,JOptionPane.ERROR_MESSAGE);
					else {
						u = (User) ms.getParams()[1];
						//ShowMessageBox("Welcome", "Login success" ,JOptionPane.INFORMATION_MESSAGE);
						SetContent(MAIN_SCREEN);
					}
				} 
				if(cmd.equals(CommandMessage.LOGOUT_USER))
				{
					SetContent(LOGIN_SCREEN);
				}
				else if(cmd.equals(CommandMessage.CREATE_USER))
				{
					if((Integer.parseInt(ms.getParams()[1].toString()))==1)
					{
						ShowMessageBox("Information", "User was added" ,JOptionPane.INFORMATION_MESSAGE);
						SetContent(LOGIN_SCREEN);
					}
					else if((Integer.parseInt(ms.getParams()[1].toString()))==-1)
						ShowMessageBox("Error", "User already exists" ,JOptionPane.ERROR_MESSAGE);
					else
						ShowMessageBox("Error", "Can't add user" ,JOptionPane.ERROR_MESSAGE);
				}
			}
			else if(ms.getCommand().equals(CommandMessage.LOGOUT_USER)) {
				ShowMessageBox("Information ", "You have been logged from another computer" ,JOptionPane.INFORMATION_MESSAGE);
				SetContent(LOGIN_SCREEN);
			}
			else if ((ms.getCommand().equals(CommandMessage.ACCEPT_OR_REJECT_ADDITIONAL_TIME)) && (ms.getParams().length > 3) && (u != null) && (u instanceof Teacher) && (u.getId() == Integer.parseInt(ms.getParams()[3].toString()))) {
				int res = Integer.parseInt(ms.getParams()[0].toString());
				if (res < 1) {
					ShowMessageBox("ERROR", "Additional time request of exam execution " + ms.getParams()[1].toString() + " was denied.", JOptionPane.ERROR_MESSAGE);
				}
				else {
					ShowMessageBox("Information", "Additional time request of exam execution " + ms.getParams()[1].toString() + " was accepted.", JOptionPane.INFORMATION_MESSAGE);;
				}

			}
		}
		else {
			msg = arg1.toString();
			if (msg.equals(ObservableClient.CONNECTION_ESTABLISHED)) {
				// Connected.
				SetContent(LOGIN_SCREEN);
			}
			if (msg.equals(ObservableClient.CONNECTION_CLOSED)) {
				// Connected.
				SetContent(CONNECTOR_SCREEN);
			}
			//ShowMessageBox("Message Received", msg ,JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	/**
	 * Show pop up message
	 * @param title Message title
	 * @param message Message content
	 * @param type Icon type
	 */
	public static void ShowMessageBox(String title, String message, int type) {
		JOptionPane.showMessageDialog(null, message, title, type);
	}
	
	public void SetContent(int screen) {
		if (currentScreen == screen)
			return;
		client.deleteObservers();
		client.addObserver(this);
		// Show appropriate screen
		switch (screen) {
			case LOGIN_SCREEN:
				// Login screen
				setContentPane(new LogInUI(client, this));
				break;
			case SETTINGS_SCREEN:
				SettingsUI s = new SettingsUI(this);
				s.BindSettings();
				setContentPane(s);
				break;
			case CREATE_USER:
				setContentPane(new CreateUserUI(client, this));
				break;
			case MAIN_SCREEN:
				setContentPane(new MainUI(client, this));
				break;
			case QUESTIONS_MANAGER_SCREEN:
				QuestionsManagerUI qmUI = new QuestionsManagerUI(client, this);
				setContentPane(qmUI);
				qmUI.UpdateUI();
				break;
			case EXAMS_MANAGER_SCREEN:
				ExamsManagerUI emUI = new ExamsManagerUI(client, this);
				setContentPane(emUI);
				emUI.UpdateUI();
				break;
			case CONNECTOR_SCREEN:
				ConnectorUI cUI = new ConnectorUI(client, this);
				setContentPane(cUI);
				if (!client.isConnected())
					cUI.Connect();
				break;
			case QUESTION_EDITOR_SCREEN:
				QuestionEditorUI qeUI = new QuestionEditorUI(client, this);
				setContentPane(qeUI);
				break;
			case EXAMS_EDITOR_SCREEN:
				ExamEditorUI eeUI = new ExamEditorUI(client, this);
				setContentPane(eeUI);
				break;
			case ADD_QUESTION_TO_EXAM_SCREEN:
				AddQuestionToExamUI aqeUI = new AddQuestionToExamUI(client, this);
				setContentPane(aqeUI);
				break;
			case TEACHER_EXAM_EXECUTION_SCREEN:
				ExamExecutionTeacherUI eetUI = new ExamExecutionTeacherUI(client, this);
				setContentPane(eetUI);
				break;
			case STUDENT_EXAM_EXECUTION_SCREEN:
				ExamExecutionStudentUI eesUI = new ExamExecutionStudentUI(client, this);
				setContentPane(eesUI);
				break;
			case PRINCIPAL_EXAM_EXECUTION_SCREEN:
				ExamExecutionPrincipalUI eepUI = new ExamExecutionPrincipalUI(client, this);
				setContentPane(eepUI);
				break;
			case TEACHER_EXAM_COMPUTERIZED_EXECUTION_SCREEN:
				ExamExecutionTeacherComputerizedUI eetcUI = new ExamExecutionTeacherComputerizedUI(client, this);
				setContentPane(eetcUI);
				break;
			case TEACHER_EXAM_MANUAL_EXECUTION_SCREEN:
				ExamExecutionTeacherManualUI eetmUI = new ExamExecutionTeacherManualUI(client, this);
				setContentPane(eetmUI);
				break;
			case EXAM_EXECUTION_FORM_SCREEN:
				ExamExecutionFormUI eef = new ExamExecutionFormUI(client, this);
				setContentPane(eef);
				break;
			case EXAM_EXECUTION_MANUAL_FORM_SCREEN:
				ManualExamExecutionFormUI mef = new ManualExamExecutionFormUI(client, this);
				setContentPane(mef);
				break;
			case EXAM_EXECUTION_MANAGER_SCREEN:
				ExamExecutionManagerUI eemf = new ExamExecutionManagerUI(client, this);
				setContentPane(eemf);
				break;
			case STUDENT_REPORT_SCREEN:
				ReportStudentUI rsUI = new ReportStudentUI(client, this);
				setContentPane(rsUI);
				rsUI.UpdateUI();
				break;
			case TEACHER_REPORT_SCREEN:
				ReportTeacherUI rtUI = new ReportTeacherUI(client, this);
				setContentPane(rtUI);
				rtUI.UpdateUI();
				break;
			case TEACHER_REPORT_EXAM_INFO_SCREEN:
				ReportTeacherInfoUI rtiUI = new ReportTeacherInfoUI(client, this);
				setContentPane(rtiUI);
				rtiUI.updateUI();
				break;
			case GRADE_APPROVAL_SCREEN:
				ExamCheckingUI ecUI = new ExamCheckingUI(client, this);
				setContentPane(ecUI);
				break;
			case MANUAL_EXAM_GRADE_APPROVAL_SCREEN:
				CheckManualExamUI cmeUI = new CheckManualExamUI(client, this);
				setContentPane(cmeUI);
				break;
			case PRINCIPAL_REPORTS_SCREEN:
				ReportPrincipalUI rpUI = new ReportPrincipalUI(client, this);
				setContentPane(rpUI);
				break;
			case PRINCIPAL_STUDENT_REPORT_SCREEN:
				 ReportStudentInfoUI rsiUI = new ReportStudentInfoUI(client, this);
				setContentPane(rsiUI);
				break;
			case PRINCIPAL_TEACHER_REPORT_SCREEN:
				 ReportForPrincipalTeacherInfoUI rfptiUI = new ReportForPrincipalTeacherInfoUI(client, this);
				setContentPane(rfptiUI);
				break;
			case PRINCIPAL_COURSE_REPORT_SCREEN:
				 ReportCourseInfoUI rciUI = new ReportCourseInfoUI(client, this);
				setContentPane(rciUI);
				break;
		
		}
		validate();
		lastScreen = currentScreen;
		currentScreen = screen;
	}
	/**
	 * Show Last Screen
	 */
	public void ShowLastScreen() {
		SetContent(lastScreen);
	}
	/**
	 * Get Last Screen
	 * @return last screen
	 */
	public int getLastScreen() {
		return lastScreen;
	}
	/**
	 * Get user
	 * @return user
	 */
	public User getUser() {
		return u;
	}
}
////
